/**
*Still to do: Add functionality to pause the queue,
 * public function CommandQueue.pause(length of time, resumeEvent, indefinite):Boolean
 *  and resume it
 * CommandQueue.resume():Boolean
 * 
 * add functionality to empty the queue
 * CommandQueue.flush();
 * 
 * add 'combinate' functionality, so that elements can be put put off
 * in a separate queue and treated like one element
 * var c:Combinated = new Combinated();//..............synchronous commands (running at one time)....t.w.
	c.add(new FadeOut(mc, 2000));- extends AbstractAsynchronousActionImpl
	c.add(new Move(mc, 1000, -20, -40));- extends AbstractAsynchronousActionImpl
	q.add(c);
*/

package com.as3.timbot.command
{
	import com.as3.timbot.command.Command
	import com.as3.timbot.command.CommandEvent;
	import com.as3.timbot.command.QueueEvent;
	import flash.events.Event;
	import com.as3.timbot.data.collections.DynamicQueue;
	
	public class CommandQueue extends AbstractCommand
	{
		private var __commandList:DynamicQueue;
		private var __queueEvent:QueueEvent;
		
		public static var QUEUEPROGRESS:String = "queueprogress";
		public static var QUEUECOMPLETE:String = "queuecomplete";
		public static var QUEUESTART:String = "queuestart";
		
		public static var ELEMENTPROGRESS:String = "elementprogress";
		public static var ELEMENTSTART:String = "elementstart";
		public static var ELEMENTCOMPLETE:String = "elementcomplete";

		public function CommandQueue():void
		{
			//if you would like a LIFO queue, you can pass in "ReverseIterator" as an argument
			__commandList = new DynamicQueue();
			__queueEvent = new QueueEvent(CommandQueue.ELEMENTCOMPLETE);
		}
		/**
		* Adds an item to the queue
		*/
		public function add(value:Command):void
		{
			__commandList.enqueue(value);
		}
		override public function execute():void
		{
			//fire a queue loadstart event........t.w.
			super.begin();
			executeNext();
		}
		public function executeNext():void
		{
			if(!__commandList.isEmpty()){
				var commandObject:Command = Command(__commandList.dequeue());
				__queueEvent.setContent(commandObject);
				commandObject.addEventListener(CommandEvent.COMPLETE,completeHandler);
				commandObject.addEventListener(CommandEvent.START,startHandler);
				commandObject.addEventListener(CommandEvent.PROGRESS,progressHandler);
				commandObject.execute();
			}else{
				//fire a queue finished event...............t.w.
				super.end();
			}
		}
		public function completeHandler(ev:CommandEvent):void
		{
			//myEvent.setContent(ev.target);//if i want to make this Command-compatible, i should fire a command event here
			super.fireEventType(__queueEvent);
			
			executeNext();
		}
		private function startHandler(ev:CommandEvent):void
		{
			//
		};
				
		private function progressHandler(ev:CommandEvent):void
		{
			//fire a queue element load progress event............t.w.
			//trace("loading "+Math.floor(ev.bytesLoaded/1024)+" / "+Math.floor(ev.bytesTotal/1024)+" kb");
		}
		
		private function timeOutHandler(ev:CommandEvent):void
		{
			//handle a load timeout here......t.w.
		}
		public function isEmpty() : Boolean
		{
			return __commandList.isEmpty();
		}
		public function getElements() : Array
		{
			return __commandList.getElements();
		}
		public function getLength() : Number
		{
			return __commandList.getLength();
		}
	
	}
}